package com.community.common.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.community.common.pojo.constant.CameraSnConstant;
import com.community.common.pojo.forcamera.entity.CameraOpenGate;
import com.community.common.pojo.forcamera.entity.CameraPersonAdd;
import com.community.common.pojo.forcamera.response.CameraOpenGateResVo;
import com.community.common.pojo.forcamera.response.CameraPersonAddResVo;
import com.community.common.pojo.forcamera.vo.ForCameraVo;
import com.community.common.service.ForCameraService;
import com.community.common.util.CacheUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * 提供给相机调用的接口
 */
@Slf4j
@Controller
@RequestMapping("forCamera")
public class ForCameraController {

    @Resource
    private ForCameraService forCameraService;

    /**
     * 根据 cmd 命令类型(新增人员-add 删除人员-delete 清空设备所有人员-clearAll) 给相机返回数据（最小间隔 5 秒，一次最多10条）
     */
    @ResponseBody
    @PostMapping("/person/cmd")
    public JSONObject cmd(@RequestBody ForCameraVo forCameraVo) {
        CameraPersonAddResVo cameraPersonAddResVo = new CameraPersonAddResVo();
//        log.info("===========================/person/cmd 【人员命令】 接收到相机请求：{}", forCameraVo);
        String sn = forCameraVo.getSn();
        if (StringUtils.isEmpty(sn)) {
//            log.warn("sn 为空 拒绝此请求 ");
            cameraPersonAddResVo.setMsg(" sn not found ");
            cameraPersonAddResVo.setSuccess(false);
            return JSONObject.parseObject(JSON.toJSONString(cameraPersonAddResVo));
        }
        // 图片访问前缀
        cameraPersonAddResVo.setSn(sn);
        List<CameraPersonAdd> cameraPersonAdd = forCameraService.getCameraPersonAdd(sn);
        cameraPersonAddResVo.setData(cameraPersonAdd);
        if (CollectionUtils.isEmpty(cameraPersonAdd)) {
            cameraPersonAddResVo.setSuccess(false);
            cameraPersonAddResVo.setMsg("no new person to add!");
        } else {
            cameraPersonAddResVo.setSuccess(true);
            cameraPersonAddResVo.setMsg("ok");
        }
        cameraPersonAddResVo.setQueueId(UUID.randomUUID().toString());
//        log.info("<===========================/person/cmd 【人员命令】 返回给相机：{}", cameraPersonAddResVo);
        return JSONObject.parseObject(JSON.toJSONString(cameraPersonAddResVo));
    }

    /**
     * 人员命令执行结果通知
     */
    @ResponseBody
    @RequestMapping("/person/result")
    public void result(@RequestBody CameraPersonAddResVo cameraPersonAddResVo) {
//        log.info("=========================== 【人员命令】 执行结果通知 {}", cameraPersonAddResVo);
        forCameraService.cmdCallback(cameraPersonAddResVo);
    }

    /**
     * 远程开闸
     * @param forCameraVo
     * @return
     */
    @ResponseBody
    @PostMapping("/setting/cmd")
    public JSONObject settingCmd(@RequestBody ForCameraVo forCameraVo) {
        CameraOpenGateResVo cameraOpenGateResVo = new CameraOpenGateResVo();
        String sn = forCameraVo.getSn();
        if (StringUtils.isEmpty(sn)) {
            log.warn("sn 为空 拒绝此请求 ");
            cameraOpenGateResVo.setMsg(" sn not found ");
            cameraOpenGateResVo.setSuccess(false);
            return JSONObject.parseObject(JSON.toJSONString(cameraOpenGateResVo));
        }
        Object obj = CameraSnConstant.snMap.get(sn);
        if(obj==null){
//            log.warn("=============="+sn+"没有人进行扫码开门============ ");
            cameraOpenGateResVo.setMsg(" no person request ");
            cameraOpenGateResVo.setSuccess(false);
            return JSONObject.parseObject(JSON.toJSONString(cameraOpenGateResVo));
        }
        CameraOpenGate cameraOpenGate = new CameraOpenGate();
        cameraOpenGate.setCmd("openGate");
        List<CameraOpenGate> dataList = new ArrayList<CameraOpenGate>();
        dataList.add(cameraOpenGate);
        cameraOpenGateResVo.setSuccess(true);
        cameraOpenGateResVo.setData(dataList);
        CameraSnConstant.snMap.remove(sn);
        log.info("opendoor  params====="+JSON.toJSONString(cameraOpenGateResVo));
        return JSONObject.parseObject(JSON.toJSONString(cameraOpenGateResVo));
    }


    /**
     * 远程开闸执行结果通知
     */
    @ResponseBody
    @RequestMapping("/setting/result")
    public void getSettingResult(@RequestBody CameraOpenGateResVo cameraOpenGateResVo) {
        log.info("=========================== 【远程开闸】 执行结果通知 {}", cameraOpenGateResVo);
        Boolean success = cameraOpenGateResVo.getSuccess();
        if(success){
            log.info("=========================== 【远程开闸】 执行成功");
            CacheUtil.OpenDoorElement openDoorElement = CacheUtil.OpenDoorElement.builder()
                    .sn(cameraOpenGateResVo.getSn())
                    .startTimeMillis(System.currentTimeMillis())
                    .status(CacheUtil.OpenDoorEnum.SUCCESS.name())
                    .build();
            CacheUtil.cache.put(cameraOpenGateResVo.getSn(),openDoorElement);
            log.info("开闸===="+JSONObject.toJSONString(openDoorElement));

        }else {
            CacheUtil.OpenDoorElement openDoorElement = CacheUtil.OpenDoorElement.builder()
                    .sn(cameraOpenGateResVo.getSn())
                    .startTimeMillis(System.currentTimeMillis())
                    .status(CacheUtil.OpenDoorEnum.FAIL.name())
                    .msg(cameraOpenGateResVo.getMsg())
                    .build();
            CacheUtil.cache.put(cameraOpenGateResVo.getSn(),openDoorElement);
            log.info("=========================== 【远程开闸】 执行失败"+cameraOpenGateResVo.getMsg()+"======================");
        }
    }

    public static void main(String[] args) throws Exception {
        CacheUtil.OpenDoorElement openDoorElement = CacheUtil.OpenDoorElement.builder()
                .sn("1")
                .startTimeMillis(System.currentTimeMillis())
                .status(CacheUtil.OpenDoorEnum.SUCCESS.name())
                .build();
        CacheUtil.cache.put("1",openDoorElement);

        Thread.sleep(3000);
        CacheUtil.cache.put("1",openDoorElement);
        CacheUtil.OpenDoorElement aasd = (CacheUtil.OpenDoorElement) CacheUtil.cache.get("1");
        System.out.println(aasd.getStatus());
    }

}
